/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.ecms.webSetting.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.ecms.webSetting.Constant.Constant;
import com.ecms.webSetting.domain.*;
import com.ecms.webSetting.repository.TailSettingRepository;
import com.ecms.webSetting.repository.WebRelateConfigRepository;
import com.ecms.webSetting.repository.WebSettingRepository;
import com.ecms.webSetting.service.WebSettingService;
import com.ecms.webSetting.service.dto.WebSettingDto;
import com.ecms.webSetting.service.dto.WebSettingQueryCriteria;
import com.ecms.webSetting.service.mapstruct.WebSettingMapper;
import com.ecms.webSetting.utils.TemplateUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.config.FileProperties;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.utils.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author ecms
* @date 2021-12-13
**/
@Service
@RequiredArgsConstructor
@Slf4j
public class WebSettingServiceImpl implements WebSettingService {
    private final WebRelateConfigRepository webRelateConfigRepository;
    private final WebSettingRepository webSettingRepository;
    private final WebSettingMapper webSettingMapper;
    private final TailSettingRepository tailSettingRepository;
    private static FileProperties properties;
    @Override
    public Map<String,Object> queryAll(WebSettingQueryCriteria criteria, Pageable pageable){
        Page<WebSetting> page = webSettingRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        List<WebSettingDto> webSettingDtos = readWebSettingData(page.getContent());
        Page<WebSettingDto> pageDto =  new PageImpl(webSettingDtos,pageable,page.getTotalElements());
        return PageUtil.toPage(pageDto);
    }

    @Override
    public List<WebSettingDto> queryAll(WebSettingQueryCriteria criteria){

        return readWebSettingData(webSettingRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    /**
     * 处理查询出来的数据
     * @param webSettings 查询出的数据
     * @return
     */
    private List<WebSettingDto> readWebSettingData( List<WebSetting> webSettings){
        List<WebSettingDto> webSettingDtos = new ArrayList<>();
        // 获取所有网页
      
        // 所有网页信息
        Map<Long, WebSetting> webSettingsCollect = webSettings.stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
        // 获取所有网页id
        List<Long> webIdCollect = webSettings.stream().map(WebSetting::getId).distinct().collect(Collectors.toList());

        // 查询出 所有网页id 关联配置
        List<WebRelateConfig> webRelateConfigs = webRelateConfigRepository.findByWebIdIn(webIdCollect);
        // 根据网页id 分组
        Map<Long, List<WebRelateConfig>> WebRelateConfigCollect = webRelateConfigs.stream().collect(Collectors.groupingBy(WebRelateConfig::getWebId));

//        WebRelateConfigs.stream().collect(  Collectors.collectingAndThen(Collectors.groupingBy(WebRelateConfig::getId,Collectors.toList(),map->new ArrayList<>(map.ge))))
        // 根据分组后数据 继续根据 type 分组
        for (Map.Entry<Long, List<WebRelateConfig>> entry : WebRelateConfigCollect.entrySet()) {
            WebSettingDto dto = new WebSettingDto();
            dto = (WebSettingDto) webSettingMapper.toDto(webSettingsCollect.get( entry.getKey()));
            //{ type : list}
            Map<String, List<WebRelateConfig>> typeCollect = entry.getValue().stream().collect(Collectors.groupingBy(WebRelateConfig::getType));
            LogoSetting logo =new LogoSetting(); ;
            List<SwiperSetting> swiperSettingList = new ArrayList<>();
            List<ProductSetting> productSettingList = new ArrayList<>();
            List<MessageSetting> messageSettingList = new ArrayList<>();
            Map< String, List<TailSetting>> tailSettings = new HashMap();
            List<TailModule> tailModuleList = new ArrayList<>();
            VideoSetting videoSetting = new VideoSetting();
            CopyrightInfoSetting copyrightInfoSetting = new CopyrightInfoSetting();
            for (Map.Entry<String, List<WebRelateConfig>> typeEntry : typeCollect.entrySet()) {
                List<WebRelateConfig>  webRelateConfigList= typeEntry.getValue();
                List<String> collect = webRelateConfigList.stream().map(WebRelateConfig::getParam).distinct().collect(Collectors.toList());
                switch ( typeEntry.getKey()){
                    case Constant.WEB_0:
                        logo = JSON.toJavaObject(JSON.parseObject(typeEntry.getValue().get(0).getParam()),LogoSetting.class);
                        break;
                    case Constant.WEB_2:
                        swiperSettingList.addAll( JSONUtil.toList(JSONUtil.parseArray(collect.toString()), SwiperSetting.class));
                        break;
                    case Constant.WEB_3:
                        videoSetting = JSON.toJavaObject(JSON.parseObject(typeEntry.getValue().get(0).getParam()),VideoSetting.class);
                        break;
                    case Constant.WEB_4:
                        productSettingList.addAll( JSONUtil.toList(JSONUtil.parseArray(collect.toString()), ProductSetting.class));
                        break;
                    case Constant.WEB_5:
                        messageSettingList.addAll( JSONUtil.toList(JSONUtil.parseArray(collect.toString()), MessageSetting.class));
                        break;
                    case Constant.WEB_6:
                        List<TailSetting> tailSettingList = JSONUtil.toList(JSONUtil.parseArray(collect.toString()), TailSetting.class);
                        // 需要将{title:'',item:'a,b,c'} 返回  TODO
                        tailSettings = tailSettingList.stream().collect(Collectors.groupingBy(TailSetting::getTitle));
                        for (Map.Entry<String, List<TailSetting>> tailEntry : tailSettings.entrySet()) {
                            TailModule tailModule = new TailModule();
                            tailModule.setTitle(tailEntry.getKey());
                            String itemTitle = String.join(",", tailEntry.getValue().stream().map(TailSetting::getItemTitle).distinct().collect(Collectors.toList()));
                            tailModule.setItemTitle(itemTitle);
                            tailModuleList.add(tailModule);
                        }

                        break;
                    case Constant.WEB_7:
                        copyrightInfoSetting = JSON.toJavaObject(JSON.parseObject(typeEntry.getValue().get(0).getParam()),CopyrightInfoSetting.class);
                        break;
                    default:
                        break;
                }

            }
            // 封装数据 返回
            dto.setLogo(logo);
            dto.setSwiperSettingList(swiperSettingList);
            dto.setVideoSetting(videoSetting);
            dto.setProductSettingList(productSettingList);
            dto.setMessageSettingList(messageSettingList);
            dto.setTailModuleList(tailModuleList);
            dto.setTailSettings(tailSettings);
            dto.setCopyrightInfoSetting(copyrightInfoSetting);
            webSettingDtos.add(dto);
        }
        return webSettingDtos;
    }
    @Override
    @Transactional
    public WebSettingDto findById(Long id) {
        WebSetting webSetting = webSettingRepository.findById(id).orElseGet(WebSetting::new);
        ValidationUtil.isNull(webSetting.getId(),"WebSetting","id",id);
        return webSettingMapper.toDto(webSetting);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebSettingDto create(WebSetting resources) {
        return webSettingMapper.toDto(webSettingRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebSettingDto create(WebSettingDto resources) {
        WebSetting webSetting =   webSettingMapper.toEntity(resources);
        webSetting.setLinkType("0");
        webSetting.setCreateBy(SecurityUtils.getCurrentUsername());
        webSetting.setUpdateBy(SecurityUtils.getCurrentUsername());

        // 保存 网页主配置
        WebSetting save = webSettingRepository.save(webSetting);
        saveWebRealteSettingData(save.getId(),resources);

        // 生成网页
        return webSettingMapper.toDto(save );
    }
    @Transactional(rollbackFor = Exception.class)
     private void saveWebRealteSettingData( Long webId ,WebSettingDto resources){
         // 保存 网页关联配置

         // 保存关联logo信息
         WebRelateConfig logoConfig = new WebRelateConfig();
//        WebRelateConfigKey logoConfigKey = new WebRelateConfigKey();
         //Logo
         LogoSetting logo = resources.getLogo();
         logoConfig.setType(Constant.WEB_0);
         logoConfig.setWebId(webId);
         logoConfig.setConfigId(String.valueOf(logo.getId()));
         logoConfig.setParam(JSON.toJSONString(logo));
         webRelateConfigRepository.save(logoConfig);

         // 保存关联轮播图信息
         List<WebRelateConfig> webRelateConfigs = new ArrayList<>();
         WebRelateConfig swiperConfig = null;
//        WebRelateConfigKey swiperConfigKey = null;
         List<SwiperSetting> swiperSettingList = resources.getSwiperSettingList();
         for (SwiperSetting swiperSetting : swiperSettingList) {
             swiperConfig = new WebRelateConfig();
             swiperConfig.setWebId(webId);
             swiperConfig.setType(Constant.WEB_2);
             swiperConfig.setConfigId(String.valueOf(swiperSetting.getId()));

             swiperConfig.setParam(JSON.toJSONString(swiperSetting));


             webRelateConfigs.add(swiperConfig);
         }
         webRelateConfigRepository.saveAll(webRelateConfigs);

         // 保存关联视频内容信息
         WebRelateConfig videoConfig = new WebRelateConfig();
//        WebRelateConfigKey videoConfigKey = new WebRelateConfigKey();

         //视频
         VideoSetting videoSetting = resources.getVideoSetting();
         videoConfig.setType(Constant.WEB_3);
         videoConfig.setWebId(webId);
         videoConfig.setConfigId(String.valueOf(videoSetting.getId()));

         videoConfig.setParam(JSON.toJSONString(videoSetting));
         webRelateConfigRepository.save(videoConfig);

         // 保存产品列表信息
         webRelateConfigs = new ArrayList<>();
         List<ProductSetting> productSettingList = resources.getProductSettingList();
         for (ProductSetting productSetting : productSettingList) {
             WebRelateConfig productConfig = new WebRelateConfig();
             productConfig.setWebId(webId);
             productConfig.setType(Constant.WEB_4);
             productConfig.setConfigId(String.valueOf(productSetting.getId()));

             productConfig.setParam(JSON.toJSONString(productSetting));
//            productConfig.setId(productConfigKey);

             webRelateConfigs.add(productConfig);
         }
         webRelateConfigRepository.saveAll(webRelateConfigs);

         // 保存最新消息
         webRelateConfigs = new ArrayList<>();
         // 消息
         List<MessageSetting> messageSettingList = resources.getMessageSettingList();
         for (MessageSetting messageSetting : messageSettingList) {
             WebRelateConfig msgConfig = new WebRelateConfig();
             msgConfig.setWebId(webId);
             msgConfig.setType(Constant.WEB_5);
             msgConfig.setConfigId(String.valueOf(messageSetting.getId()));

             msgConfig.setParam(JSON.toJSONString(messageSetting));
//            msgConfig.setId(msgConfigKey);

             webRelateConfigs.add(msgConfig);

         }
         webRelateConfigRepository.saveAll(webRelateConfigs);

         // 保存尾部信息
         webRelateConfigs = new ArrayList<>();
         // 尾部
         List<TailModule> tailSettingVoList = resources.getTailModuleList();
         List<TailSetting> tailSettingList = tailSettingRepository.findByTitleIn( tailSettingVoList.stream().map(TailModule::getTitle).distinct().collect(Collectors.toList()));
//        Map<String, List<TailSetting>> tailSettingCollect = tailSettingList.stream().collect(Collectors.groupingBy(TailSetting::getTitle));
//        for (Map.Entry<String, List<TailSetting>> entry : tailSettingCollect.entrySet()) {
//            WebRelateConfig tailConfig = new WebRelateConfig();
////            WebRelateConfigKey tailConfigKey = new WebRelateConfigKey();
//            tailConfig.setWebId(webId);
//            tailConfig.setType(Constant.WEB_6);
//            tailConfig.setConfigId(entry.getKey());
//            tailConfig.setParam(JSON.toJSONString(entry.getValue()));
//            webRelateConfigs.add(tailConfig);
//        }
//        webRelateConfigs = new ArrayList<>();

         for (TailSetting tailSetting : tailSettingList) {
             WebRelateConfig tailConfig = new WebRelateConfig();
             tailConfig.setWebId(webId);
             tailConfig.setType(Constant.WEB_6);
             tailConfig.setConfigId( String.valueOf( tailSetting.getId()));
             tailConfig.setParam(JSON.toJSONString(tailSetting));
             webRelateConfigs.add(tailConfig);
         }
         webRelateConfigRepository.saveAll(webRelateConfigs);
//        webRelateConfigRepository.saveAll(webRelateConfigs);

         // 保存版权信息
         WebRelateConfig copurightInfoConfig = new WebRelateConfig();
//        WebRelateConfigKey copurightInfoConfigKey = new WebRelateConfigKey();
         CopyrightInfoSetting copyrightInfoSetting = resources.getCopyrightInfoSetting();
         copurightInfoConfig.setType(Constant.WEB_7);
         copurightInfoConfig.setWebId(webId);
         copurightInfoConfig.setConfigId(String.valueOf(copyrightInfoSetting.getId()));

//        copurightInfoConfig.setId(copurightInfoConfigKey);
         copurightInfoConfig.setParam(JSON.toJSONString(copyrightInfoSetting));
         webRelateConfigRepository.save(copurightInfoConfig);
     }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(WebSettingDto resources) {
        WebSetting webSetting = webSettingRepository.findById(resources.getId()).orElseGet(WebSetting::new);
        ValidationUtil.isNull( webSetting.getId(),"WebSetting","id",resources.getId());
        webSetting.copy(resources);
        // 删除历史配置信息
        webRelateConfigRepository.deleteByWebId(webSetting.getId());
        // 保存关联信息
        saveWebRealteSettingData(webSetting.getId(),resources);
        // 保存主信息
        webSettingRepository.save(webSetting);
    }

    @Override
    public void deleteAll(Long[] ids) {

        for (Long id : ids) {

            webSettingRepository.deleteById(id);
        }
        webRelateConfigRepository.deleteByWebIdIn(ids);
    }

    @Override
    public void download(List<WebSettingDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (WebSettingDto webSetting : all) {
            Map<String,Object> map = new LinkedHashMap<>();

            map.put("创建者", webSetting.getCreateBy());
            map.put("更新者", webSetting.getUpdateBy());
            map.put("创建日期", webSetting.getCreateTime());
            map.put("更新时间", webSetting.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public void deploy(WebSettingDto resources) throws IOException {
        String tempPath = Constant.LANGUAGE_1.equals(resources.getLanguage())? "/ecmsWeb/en/index.html":"/ecmsWeb/cn/index.html";
        Date date = DateUtil.parse(DateUtil.now());
        String format = DateUtil.format(date, DatePattern.PURE_DATETIME_PATTERN);
//        try {
            String path = TemplateUtils.realFtlData(resources, "ecms/html/", "index.html");
            File  htmlFile = new File(path);
            if(!htmlFile.exists()){
                return;
            }
            String destPath = System.getProperty("user.dir")+tempPath;
            File destFile = new File(destPath);
            if(!destFile.exists()){
                FileUtil.touch(destFile);
            }else{
                // 备份文件
                String destPathTemp = System.getProperty("user.dir")+"/backEcmsWeb"+File.separator+format+tempPath;
                File backFile = new File(destPathTemp);
                FileUtil.move(destFile,backFile,true);
            }

            // 移动到静态文件目录
            FileUtil.move(htmlFile,destFile,true);

//        } catch (IOException e) =9哦了
//            log.error("文件生成失败"+e.getMessage());
//            throw new BadRequestException("文件生成失败 请联系管理人员"+e.getMessage());
//        }
    }




}